package cn.kgc.springbootdemo.aop;

import cn.hutool.core.lang.Validator;
import cn.kgc.springbootdemo.annotation.PreAuthorize;
import cn.kgc.springbootdemo.annotation.StopFormRepeatSubmitAnnotation;
import cn.kgc.springbootdemo.service.UserService;
import cn.kgc.springbootdemo.util.HttpUtils;
import cn.kgc.springbootdemo.vo.UserLoginVO;
import com.auth0.jwt.JWT;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * <h3>springbootdemo</h3>
 * <p>授权Aop拦截器</p>
 *
 * @author : DongZeJian
 * @date : 2021-04-13 14:24
 **/
@Slf4j
@Aspect
@Component
public class PreAuthorizeInterceptor {


    @Autowired
    private UserService userService;

    //within 是指定类里所有方法执行的逻辑
    @SneakyThrows
    @Around("@within(preAuthorize)")
    public Object apiAopTYPE(ProceedingJoinPoint proceedingJoinPoint, PreAuthorize preAuthorize) {
        return common(proceedingJoinPoint,preAuthorize);
    }

    //annotation 是指定方法上执行的逻辑
    @SneakyThrows
    @Around("@annotation(preAuthorize)")
    public Object apiAopIdempotentInterceptor(ProceedingJoinPoint proceedingJoinPoint, PreAuthorize preAuthorize) {
        return common(proceedingJoinPoint,preAuthorize);
    }

    @SneakyThrows
    public Object common(ProceedingJoinPoint proceedingJoinPoint, PreAuthorize preAuthorize){
        //获取当前请求HttpServletRequest
        HttpServletRequest request = HttpUtils.getHttpServletRequest();

        //获取token
        String token = request.getHeader("Authorization");

        //通过token 获得用户Id
        String userId = JWT.decode(token).getAudience().get(0);

        //通过用户ID获得用户登录信息及用户该角色持有的权限列表
        UserLoginVO userLoginInfoById = userService.getUserLoginInfoById(userId);

        //获得接口上必须要有的权限标识
        String value = preAuthorize.value();

        Validator.validateTrue(userLoginInfoById.getMenus().contains(value),"权限不足，请联系管理员");

        return  proceedingJoinPoint.proceed();
    }


}
